package Model;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Event Class, occurrence of EventSpecification abstraction class.
 * 
 * @author Yury Kitaev
 *
 */
public class Event 
{

	private static int nextEventId = 1000;
	private int id;
	private Date date; // date and time
	private int duration; // in minutes
	private int capacity; // in persons
	private EventSpecification specification; 
	private EventStatus status;
	private VenueTimeslot venue;
	private int seatsTaken;
	
	/** 
	 * Constructor 
 	 * @param date The date and time of the event start
	 * @param duration Duration of the event, in minutes
	 * @param capacity Maximum number of attendees
	 * @param specification Event Specification class
	 * @param venue The venue where the event is held
	 */
	public Event(Date date, int duration, int capacity,
			EventSpecification specification, EventStatus status, VenueTimeslot venue)
	{
		super();
		this.date = date;
		this.duration = duration;
		this.capacity = capacity;
		this.specification = specification;
		this.status = status;
		this.venue = venue;
		this.id = (nextEventId++);
		seatsTaken = 0;
	}

	public Date getDate() 
	{
		return date;
	}

	public void setDate(Date date) 
	{
		this.date = date;
	}

	public int getDuration() 
	{
		return duration;
	}

	public void setDuration(int duration) 
	{
		this.duration = duration;
	}

	/**
	 * Maximum number of people allowed in.
	 * @return
	 */
	public int getCapacity() 
	{
		return capacity;
	}

	public void setCapacity(int capacity)
	{
		this.capacity = capacity;
	}

	/**
	 * Tells if the event is open or closed
	 * @return
	 */
	public EventStatus getStatus() 
	{
		return status;
	}

	/**
	 * Opens or closes the event
	 * @param status Any value from EventStatus enum
	 */
	public void setStatus(EventStatus status) 
	{
		this.status = status;
	}

	public VenueTimeslot getVenue() 
	{
		return venue;
	}

	public void setVenue(VenueTimeslot venue) 
	{
		this.venue = venue;
	}

	public int getId() 
	{
		return id;
	}

	public EventSpecification getSpecification() 
	{
		return specification;
	}

	public void setSpecification(EventSpecification specification) 
	{
		this.specification = specification;
	}
	
	/**
	 * Closes the event if all seats are taken or if the amount of seats exceeds the capacity
	 */
	public void refreshStatus()
	{
		int numberOfSeatsTaken = 0;
		for (Seat s : getVenue().getSeats())
		{
			if (s.isTaken())
			{
				++numberOfSeatsTaken;
			}
		}
		
		seatsTaken = numberOfSeatsTaken;
		
		if (numberOfSeatsTaken >= getCapacity()
				|| numberOfSeatsTaken >= getVenue().getSeats().size())
		{
			setStatus(EventStatus.Closed);
		}
		else
		{
			setStatus(EventStatus.Open);
		}
	}

	/**
	 * Returns the number of seats currently taken for this event.
	 * @return
	 */
	public int getSeatsTaken() 
	{
		return seatsTaken;
	}

	@Override
	public String toString() 
	{
		SimpleDateFormat wDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat wTimeFormat = new SimpleDateFormat("HH:mm");
		
		return specification.getTitle().toUpperCase() 
				+ " on " + wDateFormat.format(date) 
				+ " at " +  wTimeFormat.format(date)
				+ " lasting " + duration + " minute(s)"
				+ " with capacity of " + capacity + " person(s)"
				+ " and is " + status.toString().toUpperCase()
				+ "; seats available: " + (getCapacity() - getSeatsTaken())
				+ ", Event ID = " + getId();
	}
}
